# -*- coding: utf-8 -*-
import numpy
from PyQt5.Qt import *
import matplotlib.pyplot as plt
import sys
import numpy as np
import time
import os
import cv2
import shutil
from scipy.optimize import curve_fit
from tools import cv_imread, create_dir
from PyQt5.QtGui import QDoubleValidator

plt.style.use('seaborn-dark')
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

"""
hl着点画图分段
"""

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("PyQt5测试小程序")
        self.resize(500, 400)
        self.setup_ui()

    def setup_ui(self):
        layout = QVBoxLayout()

        self.label = QLabel(self)
        self.label.setText("图片文件夹路径：")

        self.label.setStyleSheet("font-size:12px;color:black")

        self.FilePath=QLineEdit(self)
        self.FilePath.setText(r"F:\Python\PyWorkspace\陈裕涛\川恒磷矿(1)\实验2")
        self.FilePath.resize(285,20)

        self.btn = QPushButton(self)
        self.btn.setText("OK")

        #输入两条曲线的文本框
        wgtCurveInput=QWidget()
        layoutCurInput=QVBoxLayout()#垂直布局  垂直布局里再放两个水平布局 水平布局里面再放输入框和文本框

        wgtCurve1=QWidget()#这是一个布局
        layoutCurve1=QHBoxLayout()#水平布局

        #向水平布局里面添加文件
        lableCurve1=QLabel("curve1:")
        layoutCurve1.addWidget(lableCurve1)

        #曲线1的5个输入框
        self.textCurve11=QLineEdit("0.0000094")# 0.0000094
        layoutCurve1.addWidget(self.textCurve11)
        self.textCurve12=QLineEdit('0.2425932')# 0.2425932
        layoutCurve1.addWidget(self.textCurve12)
        self.textCurve13=QLineEdit('2784.2919352')# 2784.2919352
        layoutCurve1.addWidget(self.textCurve13)
        self.textCurve14=QLineEdit('10702')# 10702
        layoutCurve1.addWidget(self.textCurve14)
        self.textCurve15=QLineEdit('48266')# 48266
        layoutCurve1.addWidget(self.textCurve15)

        wgtCurve1.setLayout(layoutCurve1)  #第一个曲线设置布局

        #再输入一个布局
        wgtCurve2 = QWidget()  # 这是一个布局
        layoutCurve2 = QHBoxLayout()  # 水平布局

        # 向水平布局里面添加文件
        lableCurve2 = QLabel("curve2:")
        layoutCurve2.addWidget(lableCurve2)

        # 曲线2的5个输入框
        self.textCurve21 = QLineEdit("-0.0000353")# -0.0000353
        layoutCurve2.addWidget(self.textCurve21)
        self.textCurve22 = QLineEdit('2.9377212')# 2.9377212
        layoutCurve2.addWidget(self.textCurve22)
        self.textCurve23 = QLineEdit('-28629.7031576')# -28629.7031576
        layoutCurve2.addWidget(self.textCurve23)
        self.textCurve24 = QLineEdit('31507')# 31507
        layoutCurve2.addWidget(self.textCurve24)
        self.textCurve25 = QLineEdit('48383')# 48383
        layoutCurve2.addWidget(self.textCurve25)

        np.set_printoptions(precision=7, suppress=True)

        # 浮点行校验器
        doubleValidator = QDoubleValidator(self)
        doubleValidator.setRange(-100000000, 100000000)  # 设置数值范围-100000000-100000000
        doubleValidator.setNotation(QDoubleValidator.StandardNotation)  # 设置数值精度 小数点后面7位
        doubleValidator.setDecimals(7)  # 小数点后7位
        #设置校验器 保证输入的数字是浮点数 并且小数位数为7位
        for _ in [self.textCurve11,self.textCurve12,self.textCurve13,self.textCurve14,self.textCurve15,
                  self.textCurve21, self.textCurve22, self.textCurve23, self.textCurve24, self.textCurve25]:
            _.setValidator(doubleValidator)

        wgtCurve2.setLayout(layoutCurve2)  # 第一个曲线设置布局
        layoutCurInput.addWidget(wgtCurve1)
        layoutCurInput.addWidget(wgtCurve2)

        wgtCurveInput.setLayout(layoutCurInput)

        layout.addWidget(self.label)
        layout.addWidget(self.FilePath)
        layout.addWidget(self.btn)
        layout.addWidget(wgtCurveInput)

        self.setLayout(layout)
        self.btn.clicked.connect(self.hd)

    def hd(self):
        filePath=self.FilePath.text()
        print("输入的文件路径:\t",filePath,'\t',type(filePath))
        print("这一部分的代码先留着吧  拿输入框的数据并组成二维曲线")
        #####  这一部分的代码先留着吧  拿输入框的数据并组成二维曲线
        a1, b1, c1, xmin1, xmax1=self.textCurve11.text(),self.textCurve12.text(),self.textCurve13.text(),self.textCurve14.text(),self.textCurve15.text()
        a2, b2, c2, xmin2, xmax2=self.textCurve21.text(),self.textCurve22.text(),self.textCurve23.text(),self.textCurve24.text(),self.textCurve25.text()

        # 下面把字符串的数据转化为浮点型的数据  要是不能转为浮点型的数据 就是输入的数据有问题 查看一下是不是有多余逗号或者输入为空
        try:
            a1=float(a1)
            b1=float(b1)
            c1=float(c1)
            xmin1=int(xmin1)
            xmax1=int(xmax1)
            a2=float(a2)
            b2=float(b2)
            c2=float(c2)
            xmin2=int(xmin2)
            xmax2=int(xmax2)
        except:#如果不能成功的转为浮点型的数据，那就是数据可能有逗号或者为空 这里抛异常了，以后遇到了其他的情况再考虑吧！
            print("输入的数据有误，检查一下是不是有逗号或者输入为空")
            # myDialog = QDialog()
            # myDialog.resize(260,100)
            # myDialog.setWindowTitle("输入数据有问题")
            # textTip = QLabel("检查一下输入的数据是不是有逗号或者输入为空", myDialog)  # 直接就在这个对话框上面了
            # textTip.resize(260,20)#对话框的尺寸
            # myDialog.setWindowModality(Qt.ApplicationModal)  # 设置不关闭这个对话框 原来的主界面上的元素就不可用
            # myDialog.exec()
        #####  这一部分的代码先留着吧  拿输入框的数据并组成二维曲线
        #0.0000009465870929744  -0.000003534561784686101
        self.line1 = [a1, b1, c1, xmin1, xmax1]#[9.465870929744698e-06, 0.2425932587603435, 2784.291935281546, 10702, 48266]
        self.line2 = [a2, b2, c2, xmin2, xmax2]#[-3.534561784686101e-05, 2.937721219352888, -28629.703157628508, 31507, 48383]
        print(end='')#起一个不要打断注释的作用
        # 关键计算
        def get_avg_all(src, bgth, rpar):  # bgth480000  rpar=1.2
            se = np.ones((5, 5))
            box = 2

            data = []
            for file in os.listdir(src):
                if not file.endswith('tif'):
                    continue
                try:
                    img = cv_imread(os.path.join(src, file))  # 读取图片
                    imgr, imgh, imgl = cv2.split(img)  # 拆分成三通道

                    imgl = cv2.copyMakeBorder(imgl, box, box, box, box, cv2.BORDER_CONSTANT, value=65535)
                    imgh = cv2.copyMakeBorder(imgh, box, box, box, box, cv2.BORDER_CONSTANT, value=65535)
                    imgr = cv2.copyMakeBorder(imgr, box, box, box, box, cv2.BORDER_CONSTANT, value=65535)

                    bwl = imgl < bgth  # bgth=48000
                    bwl = cv2.erode(bwl.astype('uint8'), se).astype('bool')

                    L = int(np.nanmean(imgl[bwl] // 10 * 10))
                    H = int(np.nanmean(imgh[bwl] // 10 * 10))
                    R = round(np.nanmean(imgr[bwl]), 4)

                    r = round(L / H * rpar, 4)
                    Z = round(-6.956 * (10 ** 5) * np.exp(-9.815 * r) + 4.685 * np.exp(0.6783 * r), 4)

                    data.append([L, H, R, r, Z, file])  # 低能，高能，第三通道，r值图，z值图，文件名
                except:
                    pass
            return np.array(data)

        # 主函数
        def func(src, bgth=48000, rpar=1.2, x1=1, y1=0, x2=1, y2=3):#, line1=None, line2=None
            self.x_lim_all = (10000, 60000)
            self.y_lim_all = (5000, 45000)#先设置以下坐标轴的显示范围 初始化给个值

            self.points1 = []#曲线1上的点
            self.points2 = []#曲线2上的点
            #self.lines = [line1, line2]#这个lines可以删掉了，基本上用不上
            datas = {}
            self.space = False#记录一下空格键点击的次数
            self.spaceCount = 0  # 这里给按空格键记个数，通过这个数量的奇偶去更改self.space的True和False
            self.mKey = False#记录一下m点击的次数
            self.qKey=False#记录一下q点击的次数
            self.qCount = 0  # 这里给按空格键记个数，通过这个数量的奇偶去更改self.space的True和False
            #单独显示某个图片 那个图片的路径
            self.alone=''

            #下面这个line1和line2不用初始化为None了，应该是列表存储了5个数的形式，一开始要是有无输入就是空，有输入就是去替代
            # self.line1 =[9.465870929744698e-06, 0.2425932587603435, 2784.291935281546, 10702, 48266]
            # self.line2 =[-3.534561784686101e-05, 2.937721219352888, -28629.703157628508, 31507, 48383]
            self.result=''#保存的结果，保存为txt文件的格式,这个

            dealfiles = set()
            for files in os.listdir(src):
                if files in ["空场", "本底", 'empty_air', 'result']:#这里明明有result文件夹啊 那昨天那个bug怎么的来的 这里再调试一下
                    continue
                if files.endswith('.tif'):
                    dealfiles.add(os.path.split(src))
                    continue
                if os.path.isdir(os.path.join(src, files)):
                    dealfiles.add((src, files))
                    continue

            print(dealfiles, type(dealfiles), len(dealfiles))
            for src, files in dealfiles:
                data = get_avg_all(os.path.join(src, files), bgth, rpar)
                datas[files] = data
            #print(datas, type(datas))

            fig, ax = plt.subplots(1, 1)
            for files, data in datas.items():
                ax.plot((data[:, x1]).astype('float32'), (data[:, y1]).astype('float32'), '.', label=files)#x1是1 y1是0 x1是高能 y1是高能
            ax.legend()
            plt.xlabel("图片高能像素均值")
            plt.ylabel("图片低能像素均值")
            plt.show()

            #这里修改一下，分成两个函数，一个函数是输入点，返回[a,b,c,xmin,xmax]
            #写一个函数，输入一群点，返回这群点拟合出来的二次曲线，经检验，这个函数是成功了的
            def getCurve(points):
                """输入点，然后返回[a,b,c,xmin,xmax]"""
                def get_curve(x, a, b, c):
                    return a * (x ** 2) + b * x + c

                nppoints = np.asarray(points)
                popt, pcov = curve_fit(get_curve, nppoints[:, 0], nppoints[:, 1])
                a = popt[0]
                b = popt[1]
                c = popt[2]
                xmin = np.nanmin(nppoints[:, 0])
                xmax = np.nanmax(nppoints[:, 0])
                xmin = int(xmin - (xmax - xmin) / 10)
                xmax = int(xmax + (xmax - xmin) / 10)

                return [a, b, c, xmin, xmax]

            #这里写一个显示曲线的函数，输入一个line=[a,b,c,xmin,xmax] 然后把这个曲线显示在图上
            def showL(line,color,space):
                """这里的line=[a, b, c, xmin, xmax]"""
                a, b, c, xmin, xmax = line  # 拿到5个值
                #所以有了5个值以后，通过x去生成点，然后把曲线画出来
                x = np.asarray([i for i in range(xmin, xmax)], dtype='float64')

                def get_curve(x, a, b, c):
                    return a * (x ** 2) + b * x + c

                y = get_curve(x, a, b, c)
                #既然这里是画一个曲线，那就没有必要跟据颜色去区分直线1和直线2了，应该是输入了直线的颜色，直接画出来
                if color=='g' and not space:#这里是line1和line2进行切换 如果被切换到当前的线了 那就线粗一点  如果是绿色并且space=False那就是第一条信啊
                    ax.plot(x, y, 'k-',linewidth =2.0, color=color, alpha=1)
                elif color=='r' and  space:#如果是红色并且space=True那就是第二条线
                    ax.plot(x, y, 'k-', linewidth=2.0, color=color, alpha=1)
                else:
                    ax.plot(x, y, 'k-', linewidth=1, color=color, alpha=1)
                ax.legend()
                ax.figure.canvas.draw()


            def button_press(event):
                current_ax = event.inaxes
                """ 这个是鼠标单击事件的响应函数，左键和右键只是添加和减少点"""
                """除此之外，最下面又给画布上绑定了一个鼠标移动函数，达到的效果就是鼠标点击并且移动，只不过那个响应函数里只有中键"""
                if event.button == 1:#点击了鼠标左键
                    print("点击了鼠标左键")
                    ax = event.inaxes
                    x, y = event.xdata, event.ydata
                    #点击空格键 self.space在True和False之间不停的切换  self.space 最开始是 False
                    if not self.space:#如果没有点击空格键 就算是第一条线
                        self.points1.append([x, y])
                    else:#如果点击了空格键 就算是第二条线
                        self.points2.append([x, y])
                    ax.cla()
                    current_ax.set(xlim=self.x_lim_all, ylim=self.y_lim_all)
                    for files, data in datas.items():
                        ax.plot((data[:, x1]).astype('float32'), (data[:, y1]).astype('float32'), '.',
                                label=files)  # x1是1 y1是0 x1是低能 y1是高能
                    ax.scatter(np.array(self.points1)[:,0],np.array(self.points1)[:,1],color='black',marker='*',alpha=1,zorder=10)
                    #如果点击了空格键，才有第二条线上的点，才去显示这些点，注意这里可能有个bug，如果点击了空格但是没有点鼠标左键的时候,points是空的，怎么显示点？
                    if self.spaceCount>0:ax.scatter(np.array(self.points2)[:,0],np.array(self.points2)[:,1],color='black',marker='*',alpha=1,zorder=10)
                    ax.legend()
                    plt.xlabel("图片高能像素均值")
                    plt.ylabel("图片低能像素均值")

                    #如果点超过了3个就可以先把线画出来了,之前的showLine函数是直接把所有的点给放进去然后拟合出了二次曲线的参数，然后画出了线
                    #现在改成先用一个函数，把二次曲线的各个参数拟合出来，然后再拿到参数之后去画曲线
                    if len(self.points1)>2:
                        self.line1 = getCurve(self.points1)
                        showL(self.line1,'g',self.space)
                    if len(self.points2)>2:
                        self.line2 = getCurve(self.points2)
                        showL(self.line2,'r',self.space)
                    fig.canvas.draw_idle()

                if event.button == 3:#点击了鼠标右键
                    print("点击了鼠标右键，这里还有一个问题，就是只有一个点的时候,再pop就为空了，后面调试一下")
                    #这里也是通过self.space的True和False上进行切换，确定是在line1还是line2上进行操作
                    if self.points1 and not self.space:#点击右键就是去删除点
                        self.points1.pop()
                    if self.points2 and self.space:
                        self.points2.pop()

                    ax = event.inaxes
                    ax.cla()
                    current_ax.set(xlim=self.x_lim_all, ylim=self.y_lim_all)
                    for files, data in datas.items():
                        ax.plot((data[:, x1]).astype('float32'), (data[:, y1]).astype('float32'), '.',
                                label=files)  # x1是1 y1是0 x1是低能 y1是高能
                    ax.scatter(np.array(self.points1)[:, 0], np.array(self.points1)[:, 1], color='black', marker='*',alpha=1, zorder=10)
                    if self.spaceCount>0:ax.scatter(np.array(self.points2)[:,0],np.array(self.points2)[:,1],color='black',marker='*',alpha=1,zorder=10)
                    plt.xlabel("图片高能像素均值")
                    plt.ylabel("图片低能像素均值")
                    ax.legend()
                    if len(self.points1) > 2:
                        #现在把之前老的showLine函数分成两部分，得到二次曲线的几个参数，然后根据这几个参数去绘制图形
                        self.line1 = getCurve(self.points1)
                        showL(self.line1,'g',self.space)
                    if len(self.points2) > 2:
                        self.line2 = getCurve(self.points2)
                        showL(self.line2,'r',self.space)
                    fig.canvas.draw_idle()

                fig.canvas.mpl_connect('motion_notify_event', on_button_move)#鼠标点击并且移动了才会激活下面的函数
                #添加一个中键可以移动点的操作

            def on_button_move(event):#这个是鼠标移动的响应函数
                current_ax = event.inaxes
                if event.button == 2:
                    print("点击了鼠标中键")
                    ax = event.inaxes
                    x_mouse, y_mouse = event.xdata, event.ydata
                    print("鼠标此时的坐标xmouse和ymouse:",x_mouse,'\t',y_mouse)
                    ind = []#这里用一个list把跟鼠标距离很近的那个点给存储下来，存储的是这个点在points1和points2的位置索引
                    #计算一下鼠标的位置和points中的点的位置距离差
                    #这里是通过self.space的True和False，也就是点击space的次数奇偶性，去切换是在line1和line2上去更改点
                    if not self.space:
                        for i in range(len(self.points1)):
                            # 计算一下距离
                            d = np.sqrt((x_mouse - self.points1[i][0]) ** 2 + (y_mouse - self.points1[i][1]) ** 2)
                            print("当前i:",i,"\t计算的距离d:",d)
                            if d < 1000:#这里的目的是找出鼠标靠近的那个已经卯上去的点 通过距离来判断 只需要一个 并把索引记下来就OK了 下面用的时候通过索引去得到值
                                print("i:", i, "\tself.points1[i][0]:", self.points1[i][0], '\tself.points1[i][1]:', self.points1[i][1], '\td:', d)
                                ind.append(i)
                    else:
                        for i in range(len(self.points2)):
                            # 计算一下距离
                            d = np.sqrt((x_mouse - self.points2[i][0]) ** 2 + (y_mouse - self.points2[i][1]) ** 2)
                            print("当前i:",i,"\t计算的距离d:",d)
                            if d < 1000:#这里的目的是找出鼠标靠近的那个已经卯上去的点 通过距离来判断 只需要一个 并把索引记下来就OK了 下面用的时候通过索引去得到值
                                print("i:", i, "\tself.points1[i][0]:", self.points2[i][0], '\tself.points1[i][1]:', self.points2[i][1], '\td:', d)
                                ind.append(i)

                    print('ind:',ind)
                    #这里是通过self.space的True和False，也就是点击space的次数奇偶性，去切换是在line1和line2上去更改点
                    if ind and not self.space:
                        #通过索引去修改点的坐标的值
                        self.points1[ind[0]][0]=x_mouse
                        self.points1[ind[0]][1]=y_mouse
                    if ind and self.space:
                        self.points2[ind[0]][0]=x_mouse
                        self.points2[ind[0]][1]=y_mouse

                    # print("看看self.points1里面是否有更新:",self.points1)
                    ax.cla()
                    current_ax.set(xlim=self.x_lim_all, ylim=self.y_lim_all)
                    for files, data in datas.items():
                        ax.plot((data[:, x1]).astype('float32'), (data[:, y1]).astype('float32'), '.',
                                label=files)  # x1是1 y1是0 x1是低能 y1是高能
                    ax.scatter(np.array(self.points1)[:, 0], np.array(self.points1)[:, 1], color='black', marker='*',alpha=1, zorder=10)
                    if self.spaceCount>0:ax.scatter(np.array(self.points2)[:,0],np.array(self.points2)[:,1],color='black',marker='*',alpha=1,zorder=10)
                    plt.xlabel("图片高能像素均值")
                    plt.ylabel("图片低能像素均值")
                    ax.legend(loc='upper right')
                    if len(self.points1) > 2:#只要大于2个点，就可以去拟合一条曲线，然后把之前的line1给覆盖替换了
                        self.line1 = getCurve(self.points1)
                        showL(self.line1,'g',self.space)#第一条线line1是绿色，第二条线line2是红色
                    if len(self.points2) > 2:
                        self.line2 = getCurve(self.points2)#同样这里也是把line2的参数给替换了
                        showL(self.line2,'r',self.space)
                fig.canvas.draw_idle()

            def key_press(event):
                current_ax = event.inaxes
                # 空格键  点击空格键 self.space在True和False之间不停的切换 然后去切换line1和line2
                if event.key == ' ':
                    self.spaceCount += 1
                    if self.spaceCount%2==1:
                        self.space=True
                    else:
                        self.space = False
                    """ 下面这一段起的作用是按住空格键立马更新 可以删掉 只不过需要等一下才更新 有新动作"""
                    ax.cla()
                    current_ax.set(xlim=self.x_lim_all, ylim=self.y_lim_all)
                    for files, data in datas.items():
                        ax.plot((data[:, x1]).astype('float32'), (data[:, y1]).astype('float32'), '.',
                                label=files)  # x1是1 y1是0 x1是低能 y1是高能
                    ax.scatter(np.array(self.points1)[:, 0], np.array(self.points1)[:, 1], color='black', marker='*',
                               alpha=1, zorder=10)
                    # 如果点击了空格键，才有第二条线上的点，才去显示这些点，注意这里可能有个bug，如果点击了空格但是没有点鼠标左键的时候,points是空的，怎么显示点？
                    if self.spaceCount > 0: ax.scatter(np.array(self.points2)[:, 0], np.array(self.points2)[:, 1],
                                                       color='black', marker='*', alpha=1, zorder=10)
                    ax.legend()
                    plt.xlabel("图片高能像素均值")
                    plt.ylabel("图片低能像素均值")

                    # 如果点超过了3个就可以先把线画出来了,之前的showLine函数是直接把所有的点给放进去然后拟合出了二次曲线的参数，然后画出了线
                    # 现在改成先用一个函数，把二次曲线的各个参数拟合出来，然后再拿到参数之后去画曲线
                    if len(self.points1) > 2:
                        self.line1 = getCurve(self.points1)
                        showL(self.line1, 'g', self.space)
                    if len(self.points2) > 2:
                        self.line2 = getCurve(self.points2)
                        showL(self.line2, 'r', self.space)
                    fig.canvas.draw_idle()
                    """ 下面这一段起的作用是按住空格键立马更新 可以删掉 只不过需要等一下才更新 有新动作"""


                if event.key == 'q':
                    self.qCount += 1
                    if self.qCount%2==1:
                        self.qKey=True
                    else:
                        self.qKey = False

                if event.key == 'm':#m键
                    print("点击了M键:")
                    print("1:",self.line1)
                    print("2:",self.line2)

                    isDigital = True  # 判断一下line1和line2中的数据类型是不是都是整数或者浮点数
                    if isDigital:
                        for _ in self.line1:
                            if type(_) == int or type(_) == float:
                                isDigital = True
                            else:
                                isDigital = False
                        for _ in self.line2:
                            if type(_) == int or type(_) == float:
                                isDigital = True
                            else:
                                isDigital = False

                    if isDigital:
                        print("两条曲线的数字是正常的")

                        #把结果写入到txt文件
                        currentTime=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())#获取当前时间
                        self.result=''
                        self.result+=('\n'+currentTime)
                        a1, b1, c1, xmin1, xmax1=self.line1
                        a2, b2, c2, xmin2, xmax2 = self.line2
                        for files, data in datas.items():
                            x = (data[:, x1]).astype('float32')
                            y = (data[:, y1]).astype('float32')
                            idx1 = (x >= xmin1) & (x <= xmax1) & (a1 * (x ** 2) + b1 * x + c1 - y <= 0)
                            idx2 = (x >= xmin2) & (x <= xmax2) & (a2 * (x ** 2) + b2 * x + c2 - y <= 0)
                            idx = idx1 | idx2
                            all = x.shape[0]
                            waste = np.nansum(idx)
                            minecount = all - waste
                            self.result += '\n{} mine:{}/{}={:.2%}  waste: {}/{}={:.2%}'.format(files, minecount, all,
                                                                                            minecount / all,
                                                                                            waste, all, waste / all)
                        #然后把两个曲线的参数加入到self.result中去
                        line1txt = '\n曲线1方程(绿色):  {:.7f} *(x^2)+ {:.7f} *x+ {:.7f}    x范围:{}-{}'.format(a1, b1, c1, xmin1, xmax1)
                        line2txt = '\n曲线2方程(红色):  {:.7f} *(x^2)+ {:.7f} *x+ {:.7f}    x范围:{}-{}'.format(a2, b2, c2, xmin2, xmax2)
                        print("self.result:",self.result)
                        #计算一下交点
                        def get_curve(x, a, b, c):
                            return a * (x ** 2) + b * x + c
                        d=1
                        jiao_x=xmin2
                        for i in range(xmin2, xmax2+1):
                            if abs(get_curve(i,a1, b1, c1)-get_curve(i,a2, b2, c2))<d:
                                d=abs(get_curve(i,a1, b1, c1)-get_curve(i,a2, b2, c2))
                                jiao_x=i
                        print("距离很接近的点和x索引:",(d,jiao_x,get_curve(jiao_x,a1, b1, c1),get_curve(jiao_x,a2, b2, c2)))
                        intersection=(jiao_x,int(np.mean([get_curve(jiao_x,a1, b1, c1),get_curve(jiao_x,a2, b2, c2)])))
                        intersectionTxt="  两曲线交点:"+str(intersection)
                        #把结果保存为txt文件
                        with open(os.path.join(filePath, 'curves.txt'), 'a') as f:
                            linetxt ='\n'+self.result+line1txt+line2txt+intersectionTxt
                            print("linetxt:",linetxt)
                            f.write(linetxt)

                        self.mKey=True
                        ax.cla()
                        current_ax.set(xlim=self.x_lim_all, ylim=self.y_lim_all)
                        for files, data in datas.items():
                            ax.plot((data[:, x1]).astype('float32'), (data[:, y1]).astype('float32'), '.',
                                    label=files)  # x1是1 y1是0 x1是低能 y1是高能
                        if self.points1 and self.points2:#如果两个point里面是存在点的
                            if self.spaceCount > 0: ax.scatter(np.array(self.points2)[:, 0], np.array(self.points2)[:, 1],color='black', marker='*', alpha=1, zorder=10)
                            ax.scatter(np.array(self.points1)[:, 0], np.array(self.points1)[:, 1], color='black', marker='*',alpha=1, zorder=10)

                        plt.xlabel("图片高能像素均值")
                        plt.ylabel("图片低能像素均值")
                        ax.text(intersection[0],intersection[1],str(intersection)+"（交点）",color='black')
                        print("先打印一下标题:",self.result.replace(('\n'+currentTime),'')+line1txt+line2txt)
                        title=self.result.replace(('\n'+currentTime),'')+line1txt+line2txt
                        plt.title(title)

                        #这里就是直接通过line去画曲线，不需要通过points了
                        # self.line1 = getCurve(self.points1)
                        #看看空格键是否点击了 如果点击的次数是0 那就是直接从txt文件读取的参数，这个时候就生成5个点ponits1和point2 也显示在屏幕上
                        if self.spaceCount==0:
                            #去添加点,先生成5个点吧 可以生成7个点 然后首位那两个不要 有了点以后放在self.point1和2中 然后再显示
                            linshi1=np.linspace(xmin1, xmax1, 7).tolist()
                            linshi1.pop(0)
                            linshi1.pop(1)
                            for _ in linshi1:
                                self.points1.append([_,a1 * (_ ** 2) + b1 * _ + c1])
                            ax.scatter(np.array(self.points1)[:, 0], np.array(self.points1)[:, 1], color='black',
                                       marker='*', alpha=1, zorder=10)
                            linshi2=np.linspace(xmin2, xmax2, 7).tolist()
                            linshi2.pop(0)
                            linshi2.pop(1)
                            for _ in linshi2:
                                self.points2.append([_,a2 * (_ ** 2) + b2 * _ + c2])
                            ax.scatter(np.array(self.points2)[:, 0], np.array(self.points2)[:, 1], color='black',
                                       marker='*', alpha=1, zorder=10)

                        showL(self.line1, 'g',self.space)
                        showL(self.line2, 'r',self.space)

                if event.key=='c':#点击了键盘上的C键
                    print('点击了C键')
                    isDigital=True#判断一下line1和line2中的数据类型是不是都是整数或者浮点数，这个怎么好像没有怎么用上，晚点补上
                    if isDigital:
                        for _  in self.line1:
                            if type(_)==int or type(_)==float:
                                isDigital = True
                            else:
                                isDigital = False
                        for _  in self.line2:
                            if type(_)==int or type(_)==float:
                                isDigital = True
                            else:
                                isDigital = False

                    if isDigital:
                        print("两条曲线的类型都是正常的")

                        if len(self.line1)==5 and len(self.line2)==5:
                            a1, b1, c1, xmin1, xmax1 = self.line1
                            a2, b2, c2, xmin2, xmax2 = self.line2
                            create_dir(os.path.join(filePath, 'result', '精中废'))
                            create_dir(os.path.join(filePath, 'result', '废中精'))
                            create_dir(os.path.join(filePath, 'result', '废中废'))
                            create_dir(os.path.join(filePath, 'result', '精中精'))

                            for files, data in datas.items():
                                dx = (data[:, x1]).astype('float32')
                                dy = (data[:, y1]).astype('float32')

                                idx1 = (dx >= xmin1) & (dx <= xmax1) & (a1 * (dx ** 2) + b1 * dx + c1 - dy <= 0)
                                idx2 = (dx >= xmin2) & (dx <= xmax2) & (a2 * (dx ** 2) + b2 * dx + c2 - dy <= 0)
                                idx = idx1 | idx2
                                if ("低品" in files) or ("废石" in files) or ("waste" in files) or ("尾矿" in files):
                                    for file, datax, datay in zip(data[:, 5][idx], dx[idx], dy[idx]):
                                        shutil.copyfile(os.path.join(filePath, files, file),
                                                        os.path.join(filePath, 'result', '废中废',
                                                                     file[:-4] + f'_{datax}_{datay}.tif'))

                                    for file, datax, datay in zip(data[:, 5][~idx], dx[~idx], dy[~idx]):
                                        shutil.copyfile(os.path.join(filePath, files, file),
                                                        os.path.join(filePath, 'result', '精中废',
                                                                     file[:-4] + f'_{datax}_{datay}.tif'))

                                else:
                                    for file, datax, datay in zip(data[:, 5][idx], dx[idx],
                                                                  dy[idx]):
                                        shutil.copyfile(os.path.join(filePath, files, file),
                                                        os.path.join(filePath, 'result', '废中精',
                                                                     file[:-4] + f'_{datax}_{datay}.tif'))

                                    for file, datax, datay in zip(data[:, 5][~idx], dx[~idx], dy[~idx]):
                                        shutil.copyfile(os.path.join(filePath, files, file),
                                                        os.path.join(filePath, 'result', '精中精',
                                                                     file[:-4] + f'_{datax}_{datay}.tif'))

                if event.key == 'z':
                    print("点击了z键")
                    if self.qKey:
                        print("单独显示图片路径:\t",self.alone)
                        lujing=''
                        for file in os.listdir(src):
                            if os.path.exists(os.path.join(src, file,self.alone)):
                                print(os.path.join(src, file,self.alone),type(os.path.join(src, file,self.alone)))
                                lujing=os.path.join(src, file,self.alone)
                        img = cv_imread(lujing)
                        imgz, imgh, imgl = cv2.split(img)
                        bwl = imgl < bgth
                        bwl = cv2.erode(bwl.astype('uint8'), np.ones((5, 5))).astype('bool')

                        fig1, ax1 = plt.subplots(2, 3)
                        ax1[0, 0].imshow(cv2.cvtColor((img // 257).astype('uint8'), cv2.COLOR_BGR2RGB))
                        ax1[0, 1].imshow(imgl, cmap='gray')
                        ax1[0, 2].imshow(imgh, cmap='gray')

                        ax1[1, 0].scatter(imgh[bwl], imgl[bwl], s=1, label='石头区域高-低能分布')
                        ax1[1, 1].hist(imgl[bwl], 50, label='低能直方图')
                        ax1[1, 2].hist(imgh[bwl], 50, label='高能直方图')

                        ax1[0, 0].set_title('原图/255')
                        ax1[0, 1].set_title('低能图')
                        ax1[0, 2].set_title('高能图')

                        ax1[1, 0].legend()
                        ax1[1, 1].legend()
                        ax1[1, 2].legend()
                        plt.suptitle(self.alone)

                        # cv2.imshow(f'{self.alone}', img)
                        # cv2.waitKey(1)
                        plt.show()

            def btn_mvqz(event):
                current_ax = event.inaxes
                print("进入了这个移动事件")
                if self.qKey:#只有q的时候 才去进行显示那个文字提示 先把所有的点和线都显示出来先
                    print("q键处于激活状态")
                    ax = event.inaxes
                    print("event.data数据类型:", type(event.xdata), type(event.ydata))
                    if type(event.xdata)==numpy.float64 and type(event.ydata)==numpy.float64:
                        x_mouse, y_mouse = int(event.xdata), int(event.ydata)

                        ax.cla()
                        current_ax.set(xlim=self.x_lim_all,ylim=self.y_lim_all)
                        for files, data in datas.items():#x1=1, y1=0
                            ax.plot((data[:, x1]).astype('float32'), (data[:, y1]).astype('float32'), '.',
                                    label=files)  # x1是1 y1是0 x1是低能 y1是高能
                        if  len(self.points1)>0 and len(self.points2)>0:
                            ax.scatter(np.array(self.points1)[:, 0], np.array(self.points1)[:, 1], color='black', marker='*',
                                       alpha=1, zorder=10)
                            if self.spaceCount > 0: ax.scatter(np.array(self.points2)[:, 0], np.array(self.points2)[:, 1],
                                                               color='black', marker='*', alpha=1, zorder=10)
                        ax.legend()
                        plt.xlabel("图片高能像素均值")
                        plt.ylabel("图片低能像素均值")

                        if len(self.points1) > 2:  # 只要大于2个点，就可以去拟合一条曲线，然后把之前的line1给覆盖替换了
                            self.line1 = getCurve(self.points1)
                            showL(self.line1, 'g',self.space)  # 第一条线line1是绿色，第二条线line2是红色
                        if len(self.points2) > 2:
                            self.line2 = getCurve(self.points2)  # 同样这里也是把line2的参数给替换了
                            showL(self.line2, 'r',self.space)

                        #写一个列表推导式 把所有的坐标放在一个list里面 然后通过去查找
                        xyDct={}
                        for files,data in datas.items():
                            for _ in data:
                                xyDct[(int(_[x1])//255,int(_[y1])//255)]=_[5]

                        mouse=(x_mouse,y_mouse)
                        print("当前的坐标点:",mouse,"\t类型:",type(mouse))
                        if (x_mouse//255,y_mouse//255) in xyDct:
                            print(" 听说我又王牌 你是一只小小鸟 :")
                            self.alone=xyDct[(x_mouse//255,y_mouse//255)]
                            ax.text(x_mouse, y_mouse,xyDct[(x_mouse//255,y_mouse//255)])

                        # print(type(xyLst[0][0]))
                        # print("列表的长度:",len(xyLst))

                        # def list2csv(lst, name):
                        #     df = pd.DataFrame(lst)
                        #     name = "./" + name + ".csv"
                        #     df.to_csv(name, index=False)
                        #
                        # list2csv(xyLst,"所有坐标")
                        # pass
                        # for files, data in datas.items():#x1=1, y1=0   x1代表高能像素均值 实际上就是x  y1代表低能像素均值 实际上就是y
                        #     idx = np.where((data[:, x1].astype('float32') // 255 == x_mouse // 255) & (
                        #             data[:, y1].astype('float32') // 255 == y_mouse// 255))
                        #     print("data\t",data,type(data),len(data))
                        #     print("idx\t",idx,type(idx))
                        #     filename = data[:, 5][idx][0]
                        #     ax.text(x_mouse, x_mouse, filename)
                        #     ax.figure.canvas.draw()
                        #     ax.texts[-1].remove()
                        fig.canvas.draw_idle()
                else:
                    pass

            def enlarge(event):
                current_ax = event.inaxes
                """这个先给注释了吧，先把别的给调好了再说  这个短时间内还没有想到好的解决方法 后期想到方法了再说"""
                # global self.x_lim_all
                # global self.y_lim_all
                print("")
                x, y = event.xdata, event.ydata
                xmin, xmax = event.inaxes.get_xlim()
                ymin, ymax = event.inaxes.get_ylim()
                x_step1, x_step2 = (x - xmin) / 10, (xmax - x) / 10
                y_step1, y_step2 = (y - ymin) / 10, (ymax - y) / 10

                if event.button == 'up':
                    print("鼠标往上滚动了")
                    self.x_lim_all = (xmin + x_step1, xmax - x_step2)
                    self.y_lim_all = (ymin + y_step1, ymax - y_step2)
                    print("向上滚动当前的self.x_lim_all:\t", self.x_lim_all, "\t\t当前的self.y_lim_all:\t", self.y_lim_all)
                    current_ax.set(xlim=self.x_lim_all,
                                   ylim=self.y_lim_all)
                    # event.inaxes.figure.canvas.draw()
                    # return
                if event.button == 'down':
                    print("鼠标往下滚动了")
                    self.x_lim_all = (xmin - x_step1, xmax + x_step2)
                    self.y_lim_all = (ymin - y_step1, ymax + y_step2)
                    print("向下下下的self.x_lim_all:\t", self.x_lim_all, "\t\t当前的self.y_lim_all:\t", self.y_lim_all)
                    current_ax.set(xlim=self.x_lim_all,
                                   ylim=self.y_lim_all)
                    # event.inaxes.figure.canvas.draw()
                    # return
                fig.canvas.draw_idle()


            # 鼠标释放事件，鼠标松开的时候，就把上面鼠标点击并且移动的关系解绑  这样鼠标松开的时候 就不会拖动点了
            def on_button_release(event):
                fig.canvas.mpl_disconnect(fig.canvas.mpl_connect('motion_notify_event', on_button_move))#

            fig.canvas.mpl_disconnect(fig.canvas.manager.key_press_handler_id)  # 取消默认快捷键的注册
            fig.canvas.mpl_connect('button_press_event', button_press)#鼠标点击
            fig.canvas.mpl_connect('key_press_event', key_press)#键盘点击
            fig.canvas.mpl_connect('button_release_event', on_button_release)  # 鼠标松开
            fig.canvas.mpl_connect('motion_notify_event', btn_mvqz)
            fig.canvas.mpl_connect('scroll_event', enlarge)  # 鼠标滚轮放大缩小

        func(filePath)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())